﻿using McsUtility;
using McsUtility.Models;
using NodeServer.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NodeServer
{
    public partial class FrmMain : Form
    {
        #region 类成员及变量
        private AppState CurrentState = AppState.Stoped;
        TcpForwardServer tfserver = new TcpForwardServer();

        private delegate void ShowMsg(string msg);
        private ShowMsg addMsgDelegate;


        private static bool disMsg = true;

        #endregion

        public FrmMain()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                SetAppState(AppState.Starting);
                tfserver.LocalIp = txtIp.Text.Trim();
                tfserver.LocalPort = ushort.Parse(txtPort.Text.Trim());
                tfserver.ServerIp = txtServerIp.Text.Trim();
                tfserver.ServerPort = ushort.Parse(txtServerPort.Text.Trim());
                tfserver.MaxConnectionCount = 5000;
                if (tfserver.Start())
                {
                    SetAppState(AppState.Started);

                }
                SaveConfig();
            }
            catch (Exception ex)
            {
                AddMsg(ex.Message);
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            SetAppState(AppState.Stoping);

            // 停止服务
            AddMsg("$Server Stop");
            if (tfserver.Stop())
            {
                SetAppState(AppState.Stoped);
            }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            Init();
        }

        #region 同步UI数据

        /// <summary>
        /// 设置程序状态
        /// </summary>
        /// <param name="state"></param>
        private void SetAppState(AppState state)
        {
            btnStart.Invoke(new Action(() =>
            {
                CurrentState = state;
                btnStart.Enabled = (CurrentState == AppState.Stoped);
            }));
            btnStop.Invoke(new Action(() =>
            {
                CurrentState = state;
                btnStop.Enabled = (CurrentState == AppState.Started);
            }));
        }

        /// <summary>
        /// 往listbox加一条项目
        /// </summary>
        void AddMsg(string msg)
        {
            if (!disMsg) return;

            if (this.lbxMsg.InvokeRequired)
            {
                this.lbxMsg.Invoke(addMsgDelegate, msg);
            }
            else
            {
                if (this.lbxMsg.Items.Count > 100)
                {
                    this.lbxMsg.Items.RemoveAt(0);
                }
                this.lbxMsg.Items.Add(msg);
                this.lbxMsg.TopIndex = this.lbxMsg.Items.Count - (int)(this.lbxMsg.Height / this.lbxMsg.ItemHeight);
            }
        }
        private void lbxMsg_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 'c' || e.KeyChar == 'C')
            {
                this.lbxMsg.Items.Clear();
            }
        }
        #endregion

        #region 初始化
        private void Init()
        {

            ReadConfig();

            SetAppState(CurrentState);
            addMsgDelegate = new ShowMsg(AddMsg);

            InitServer();
        }

        private void InitServer()
        {
            try
            {
                tfserver.OnMessage += new EventHandler<MsgEventArgs>(TfserverOnMessage);
                tfserver.OnShutdown += new EventHandler<EventArgs>(Tfserver_OnShutdown);
                SetAppState(AppState.Stoped);
            }
            catch (Exception ex)
            {
                SetAppState(AppState.Error);
                AddMsg(ex.Message);
            }
        }

        private void Tfserver_OnShutdown(object sender, EventArgs e)
        {
            this.Invoke(new Action(() => { SetAppState(AppState.Stoped); }));
        }

        private void TfserverOnMessage(object sender, MsgEventArgs e)
        {
            AddMsg(e.Message);
        }
        #endregion


        #region 配置操作
        private void SaveConfig()
        {
            string showMsg = cbShowMsg.Checked ? "YES" : "NO";
            string ip = this.txtIp.Text.Trim();
            string port = this.txtPort.Text.Trim();
            string serverIp = this.txtServerIp.Text.Trim();
            string serverPort = this.txtServerPort.Text.Trim();

            IniHelper.INIWriteValue(Definitions.ConfigPath, "Settings", "Msg", showMsg);
            IniHelper.INIWriteValue(Definitions.ConfigPath, "Settings", "Ip", ip);
            IniHelper.INIWriteValue(Definitions.ConfigPath, "Settings", "Port", port);
            IniHelper.INIWriteValue(Definitions.ConfigPath, "Settings", "ServerIp", serverIp);
            IniHelper.INIWriteValue(Definitions.ConfigPath, "Settings", "ServerPort", serverPort);
        }
        private void ReadConfig()
        {
            var showMsg = IniHelper.INIGetStringValue(Definitions.ConfigPath, "Settings", "Msg", "NO");
            cbShowMsg.Checked = showMsg == "YES" ? true : false;
            disMsg = cbShowMsg.Checked;
            this.txtIp.Text = IniHelper.INIGetStringValue(Definitions.ConfigPath, "Settings", "Ip", "0.0.0.0");
            this.txtPort.Text = IniHelper.INIGetStringValue(Definitions.ConfigPath, "Settings", "Port", "55555");
            this.txtServerIp.Text = IniHelper.INIGetStringValue(Definitions.ConfigPath, "Settings", "ServerIp", "0.0.0.0");
            this.txtServerPort.Text = IniHelper.INIGetStringValue(Definitions.ConfigPath, "Settings", "ServerPort", "6666");
        }
        #endregion

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            tfserver.Stop();
            SaveConfig();
        }

        private void cbShowMsg_Click(object sender, EventArgs e)
        {
            disMsg = this.cbShowMsg.Checked;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            tfserver.MinerReAccept((IntPtr)Convert.ToInt32(this.textBox1.Text));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            tfserver.NodeServerMinerManagerModifyOrePoolUrl((IntPtr)Convert.ToInt32(this.textBox1.Text));
        }

        private void button3_Click(object sender, EventArgs e)
        {
            tfserver.CommServerMinerManagerStartMining((IntPtr)Convert.ToInt32(this.textBox1.Text));
        }

        private void button4_Click(object sender, EventArgs e)
        {
            tfserver.CommServerMinerManagerEndMining((IntPtr)Convert.ToInt32(this.textBox1.Text));
        }

        private void button5_Click(object sender, EventArgs e)
        {
            tfserver.CommServerMinerManagerReset((IntPtr)Convert.ToInt32(this.textBox1.Text));
        }
    }
}
